07. Stream PCD

Header Text

Stream PCD

Streamed PCD

Playing back the pcd files.

Playing back the pcd files.

Stream PCD with PCL

In the previous concept you were able to process obstacle detections on a single pcd file, now you are going to be using that same processing pipeline on multiple pcd files. To do this you can slightly modify the previous used cityBlock function from environment.cpp to support some additional arguments. Now, you will be passing in the point processor to the cityBlock function, this is because you don't want to have to recreate this object at every frame. Also the point cloud input will vary from frame to frame, so input point cloud will now become an input argument for cityBlock . The cityBlock function header should now look like this, and you no longer create the point processor or load a point cloud from inside the function.

cityBlock new Function Signature

void cityBlock(pcl::visualization::PCLVisualizer::Ptr& viewer, ProcessPointClouds<pcl::PointXYZI>* pointProcessorI, const pcl::PointCloud<pcl::PointXYZI>::Ptr& inputCloud)

Notice that in the function header you can optionally make inputCloud a constant reference by doing const and & at the end of the variable definition. You don't have to do this but you are not actually changing the inputCloud at all, just using it as an input for your point processor function. The benefit of using a constant reference is better memory efficiency, since you don't have to write to that variable's memory, just read from it, so it's a slight performance increase. If you do make this a const reference though, make sure not to modify it, or else you will get a compile error.

Code inside main

So now instead of creating your point processor, and loading pcl files from inside cityBlock you will do this inside the main function in environment.cpp right after where the pcl viewer camera position is set up.

ProcessPointClouds<pcl::PointXYZI>* pointProcessorI = new ProcessPointClouds<pcl::PointXYZI>();
std::vector<boost::filesystem::path> stream = pointProcessorI->streamPcd("../src/sensors/data/pcd/data_1");
auto streamIterator = stream.begin();
pcl::PointCloud<pcl::PointXYZI>::Ptr inputCloudI;

In the code above, you are making use of a new method from point processor called, streamPcd . You tell streamPcd a folder directory that contains all the sequentially ordered pcd files you want to process, and it returns a chronologically ordered vector of all those file names, called stream . You can then go through the stream vector in a couple of ways, one option is to use an iterator. At the end of the above code block, a variable for the input point cloud is also set up.

PCL Viewer Update Loop

The final thing to look at is the pcl viewer run cycle which is down at the bottom of envrionment.cpp . while the pcl viewer hasn't stopped, you want to process a new frame, do obstacle detection on it, and then view the results. Let's see how to set up this pcl viewer run cycle method below.

while (!viewer->wasStopped ())
{

  // Clear viewer
  viewer->removeAllPointClouds();
  viewer->removeAllShapes();

  // Load pcd and run obstacle detection process
  inputCloudI = pointProcessorI->loadPcd((*streamIterator).string());
  cityBlock(viewer, pointProcessorI, inputCloudI);

  streamIterator++;
  if(streamIterator == stream.end())
    streamIterator = stream.begin();

  viewer->spinOnce ();
}

The first thing the above method does is clear any previous rendered point clouds or shapes. Next it loads up your point cloud using your point processor and stream iterator. Then it calls your cityBlock function, and updates the iterator. If the iterator hits the end of the vector it simply sets it back to the beginning and that's it. The viewer->spinOnce() call controls the frame rate, by default it waits 1 time step, which would make it run as fast as possible. Depending on how timing efficient your obstacle detection functions were set up the faster the viewer's frame rate will be. If you want to check out the input pcd data at the fastest rate then run the code above and only run a single renderPointCloud on the input cloud inside cityBlock . Let's check out the results of the streaming pcd viewer below.

Streamed Obstacle Detection

Instructions

Instructions

  • Modify environment.cpp with the above changes
  • Call cityBlock to perform obstacle detection on each frame

Workspace

This section contains either a workspace (it can be a Jupyter Notebook workspace or an online code editor work space, etc.) and it cannot be automatically downloaded to be generated here. Please access the classroom with your account and manually download the workspace to your local machine. Note that for some courses, Udacity upload the workspace files onto https://github.com/udacity , so you may be able to download them there.

Workspace Information:

  • Default file path:
  • Workspace type: react
  • Opened files (when workspace is loaded): n/a

Solution

ND313 C1 L4 A20 Stream PCD - Solution